<template>
    <div class="ask-upload-main-box">
        <ask-upload2
            ref="askUploadRef"
            v-model="fileList"
            name="file"
            :disabled="disabled"
            :action="$staticUrl"
            :data="uploadData"
            :option="defaultOption"
            @change="handleChange"
            @on-preview="handlePictureCardPreview"
            :before-upload="_beforeUpload"
        >
            <slot></slot>
            <!-- @on-video-cover-cropend="handleVideoCover" -->
        </ask-upload2>
        <el-dialog :visible.sync="previewDialog" append-to-body>
            <template v-if="_typeIsImage">
                <img width="100%" :src="previewImgUrl" alt="image" />
            </template>
            <template v-else>
                <video
                    style="max-width: 100%;"
                    ref="previewVideoRef"
                    class="el-upload-list__item-video-preview"
                    controls
                    name="media"
                >
                    <source :src="previewImgUrl" type="video/mp4" />
                </video>
            </template>
        </el-dialog>
    </div>
</template>
<script lang="ts">
import { Component, Mixins, Prop, Watch } from "vue-property-decorator";
import { getUUID, merge } from "@/utils";
import AuthMixin from "./auth.mixin";

@Component({
    model: {
        prop: "value",
        event: "change"
    },
    name: "AskUpload"
})
export default class AskUpload extends Mixins(AuthMixin) {
    @Prop({
        type: [Object, Array],
        default: () => {
            return {};
        }
    })
    readonly value!: any | any[];

    @Prop({
        type: Object,
        default: () => {
            return {};
        }
    })
    readonly option!: any;

    @Prop({
        type: Boolean,
        default: false
    })
    readonly disabled!: boolean;

    @Prop({
        type: String,
        default: ""
    })
    readonly path!: string;

    @Prop({
        type: Boolean,
        default: false
    })
    readonly coverUpload!: boolean;

    @Prop({
        type: Function,
        default: () => {
            return Promise.resolve(true);
        }
    })
    readonly beforeUpload!: any;

    previewDialog = false;
    previewImgUrl = "";
    fileList: any[] = [];
    defaultOption: any = {
        limit: {},
        suffix: {}
    };

    sourceList: any[] = [];
    uploadData: any = {
        signature: '',
        "x-cos-security-token": "",
        "Content-Type": "",
        key: "",
        dir: "",
        host: ""
    };

    get _typeIsImage() {
        const _hasOption = this.option && this.option.type;
        return (
            !_hasOption || (_hasOption && this.defaultOption.type === "image")
        );
    }

    get _typeIsFile() {
        const _hasOption = this.option && this.option.type;
        return (
            !_hasOption || (_hasOption && this.defaultOption.type === "file")
        );
    }

    _beforeUpload(file: any) {
        return new Promise((resolve: any, reject: any) => {
            const uploadPolicy = () => {
                const _path = this.path + new Date().format('yyyy-MM-dd') + "/";
                this.getAuthorization({ Method: 'POST', Pathname: '/' })
                    .then((info: any) => {
                        this.uploadData.signature = info.Authorization;
                        this.uploadData['x-cos-security-token'] = info.XCosSecurityToken;
                        this.uploadData['Content-Type'] = "";
                        this.uploadData.key = _path + getUUID() + "." + file.file.type.split("/")[1];
                        this.uploadData.dir = _path;
                        this.uploadData.host = this.$staticUrl;
                        this.sourceList.push({
                            _id: file._id,
                            url: this.uploadData.key,
                            host: this.uploadData.host
                        });
                        resolve(true);
                    })
                    .catch((err: any) => {
                        console.log(err);
                        this.$message.error({
                            message: err.message || err.content || "接口请求失败",
                            type: "error",
                            duration: 1500
                        });
                        return reject(new Error(err));
                    });
            };
            this.beforeUpload().then((r: boolean) => {
                if (r) {
                    uploadPolicy();
                }
            });
        });
    }

    async handleVideoCover(file: any) {
        if (file.status === "parseFail" || !this.coverUpload) return;
        const _coverFile: any = {};
        _coverFile._id = file._id;
        _coverFile.file = file.covers[0].file;
        await this._beforeUpload(_coverFile);
        const askUploadRef: any = this.$refs.askUploadRef;
        askUploadRef.uploadFile(file, _coverFile.file);
    }

    handlePictureCardPreview(file: any) {
        this.previewImgUrl = file.url;
        this.previewDialog = true;
    }

    handleChange(file: any) {
        this.emitChange(file);
    }

    async emitChange(file: any) {
        if (file.status === "success") {
            const _index = this.sourceList.findIndex(
                (cur: any) => cur._id === file._id
            );
            if (_index !== -1) {
                const _cur = this.sourceList[_index];
                const askUploadRef: any = this.$refs.askUploadRef;
                askUploadRef.revokeUrl(file);
                if (this._typeIsFile) {
                    file.url = _cur.host + "/" + _cur.url;
                } else {
                    if (this._typeIsImage) {
                        const isGif = file.file.type === "image/gif";
                        file.url =
                            _cur.host +
                            "/" +
                            _cur.url +
                            (isGif
                                ? "?x-oss-process=style/tzy-rule-gif"
                                : "?x-oss-process=style/app-resource-photo");
                        if (file.img) {
                            file.url += `&width=${file.img.width ||
                                0}&height=${file.img.height || 0}`;
                        }
                    } else {
                        const _isVideo = _cur.url.indexOf(".mp4") !== -1;
                        if (_isVideo) {
                            file.url = _cur.host + "/" + _cur.url;
                            await this.handleVideoCover(file);
                        } else {
                            let _file = null;
                            if (Array.isArray(this.fileList)) {
                                const _fileIndex = this.fileList.findIndex(
                                    (cur: any) => cur._id === file._id
                                );
                                if (_fileIndex !== -1) {
                                    _file = this.fileList[_fileIndex];
                                }
                            } else {
                                _file = this.fileList;
                            }
                            if (_file) {
                                _file.status = "success";
                                _file.coverUrl =
                                    _cur.host +
                                    "/" +
                                    _cur.url +
                                    "?x-oss-process=style/app-resource-photo";
                            }
                        }
                    }
                }

                this.sourceList.splice(_index, 1);
            }
        }
        if (this.sourceList.length === 0) {
            this.$emit("change", this.fileList);
            this.$emit("blur", this.fileList);
        }
        // let successNum = 0
        // this.fileList = fileList = fileList.map(file => {
        //     if (file.status === "success") {
        //         successNum++
        //         let _index = this.sourceList.findIndex(
        //             cur => cur.uid === file.uid
        //         )
        //         if (_index !== -1) {
        //             let _cur = this.sourceList[_index]
        //             if (this.type === "image") {
        //                 let isGif = file.raw.type === "image/gif"
        //                 file.url =
        //                     _cur.host +
        //                     "/" +
        //                     _cur.url +
        //                     (isGif
        //                         ? "?x-oss-process=style/tzy-rule-gif"
        //                         : "?x-oss-process=style/app-resource-photo")
        //             } else {
        //                 file.url = _cur.host + "/" + _cur.url
        //             }
        //             this.sourceList.splice(_index, 1)
        //         }
        //     }
        //     return file
        // })
        // if (successNum === fileList.length) {
        //     let _fileList = fileList.map(cur => cur.url)
        //     if (this.model === "single") {
        //         _fileList = _fileList[0] || ""
        //     }
        //     this.$emit("change", _fileList)
        //     this.$emit("blur", _fileList)
        // }
    }

    @Watch("value", { immediate: true, deep: true })
    onValueChange(val: any) {
        this.fileList = val;
    }

    @Watch("previewDialog", { immediate: true })
    onPreviewDialogChange(val: any) {
        if (!val) {
            this.previewImgUrl = "";
            const previewVideoRef: any = this.$refs.previewVideoRef;
            previewVideoRef && previewVideoRef.pause();
        }
    }

    @Watch("option", { immediate: true, deep: true })
    onOptionChange() {
        this.defaultOption = merge(true, {}, this.defaultOption, this.option);
    }
}
</script>
